package com.witmore.neutron.ai.mcp.server.trading.scheduler;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.jk.common.utils.LocalDateUtils;
import com.witmore.neutron.ai.mcp.server.trading.db.entity.ScorpionStockAbnormalRecordDO;
import com.witmore.neutron.ai.mcp.server.trading.db.entity.ScorpionUserStockRelationDO;
import com.witmore.neutron.ai.mcp.server.trading.db.mapper.ScorpionStockAbnormalRecordMapper;
import com.witmore.neutron.ai.mcp.server.trading.db.mapper.ScorpionUserStockRelationMapper;
import com.witmore.neutron.ai.mcp.server.trading.dto.*;
import com.witmore.neutron.ai.mcp.server.trading.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.List;

/**
 * 股票异动预警定时任务执行器
 *
 * @author 豆子高
 * @since 2025-01-27
 */
@Slf4j
@Component
public class StockAbnormalAlertTask {

    @Autowired
    private IAkShareMcpService akShareMcpService;

    @Autowired
    private ScorpionUserStockRelationMapper stockRelationMapper;

    @Autowired
    private WechatNotificationService wechatNotificationService;

    @Autowired
    private ScorpionStockAbnormalRecordMapper abnormalRecordMapper;

    @Autowired
    private AbnormalReportService abnormalReportService;

    @Autowired
    private AbnormalPdfReportService abnormalPdfReportService;

    @Autowired
    private OssUploadService ossUploadService;

    @Autowired
    private StockAnalysisService stockAnalysisService;

    @Autowired
    private StockAIAnalysisService stockAIAnalysisService;

    /**
     * 执行异动预警检查任务
     *
     * @param userId    用户ID
     * @param stockCode 股票代码
     */
    public void executeAlertTask(Long userId, String stockCode) {
        log.info("执行异动预警检查任务 - 用户ID: {}, 股票代码: {}", userId, stockCode);

        try {
            // 1. 获取用户股票配置
            ScorpionUserStockRelationDO stockRelation = getUserStockRelation(userId, stockCode);
            if (stockRelation == null || stockRelation.getAlertPushEnabled() != 1) {
                log.warn("用户股票配置不存在或未开启预警 - 用户ID: {}, 股票代码: {}", userId, stockCode);
                return;
            }

            // 2. 获取股票实时数据 调用 akShareMcpService.stockIndividualInfoEm(stockCode)
            StockRealTimeInfoSingleResponse stockData = getStockRealTimeData(stockCode);
            if (stockData == null || !"200".equals(stockData.errCode()) || stockData.data() == null) {
                log.warn("获取股票实时数据失败 - 股票代码: {}, 错误信息: {}", stockCode,
                        stockData != null ? stockData.errMsg() : "数据为空");
                return;
            }

            // 3. 解析预警配置 alert_config 里面的字段
            AlertConfig alertConfig = JSONObject.parseObject(stockRelation.getAlertConfig(), AlertConfig.class);
            if (alertConfig == null) {
                log.warn("解析预警配置失败 - 用户ID: {}, 股票代码: {}", userId, stockCode);
                return;
            }

            // 4. 对比预警配置的阈值，分析股票数据并检查异动
            StockAnalysisResult analysisResult = analyzeStockData(stockData.data(), alertConfig, stockCode, userId);
            if (analysisResult != null) {
                if (analysisResult.isAbnormal()) {
                    // 5. 记录异动数据到数据库
                    ScorpionStockAbnormalRecordDO scorpionStockAbnormalRecordDO = recordAbnormalData(userId, stockCode, stockData, analysisResult, alertConfig);

                    if (scorpionStockAbnormalRecordDO == null){
                        log.warn("记录异动数据失败 - 用户ID: {}, 股票代码: {}", userId, stockCode);
                        return;
                    }
                    analysisResult.setAbnormalRecordId(scorpionStockAbnormalRecordDO.getId());
                    // 6. 如果触发预警条件，发送推送消息 微信服务号推送消息
                    sendAlertNotification(userId, stockCode, analysisResult);

                    // 7. 如果触发预警条件，生成一份HTML报告并存入表中
//                    generateAbnormalHtmlReport(userId, stockCode, stockData, analysisResult, alertConfig);

                    log.info("检测到股票异动并已记录 - 用户ID: {}, 股票代码: {}, 异动类型: {}, 涨跌幅: {}%",
                            userId, stockCode, analysisResult.getAbnormalType(), analysisResult.getChangeRatio());
                } else if (analysisResult.isFirstRecord()) {
                    // 首次记录，需要记录当前数据作为基准
                    recordCurrentStockData(userId, stockCode, stockData, analysisResult);
                    log.info("首次记录股票数据 - 用户ID: {}, 股票代码: {}, 当前价: {}",
                            userId, stockCode, analysisResult.getCurrentPrice());
                } else if (analysisResult.getChangeRatio().compareTo(BigDecimal.ZERO) != 0) {
                    // 有价格变化但未触发预警，不记录当前数据
                    log.debug("股票价格有变化但未触发预警，已记录当前数据 - 用户ID: {}, 股票代码: {}, 当前价: {}, 涨跌幅: {}%",
                            userId, stockCode, analysisResult.getCurrentPrice(), analysisResult.getChangeRatio());
                } else {
                    // 价格无变化，不记录
                    log.debug("股票价格无变化，跳过记录 - 用户ID: {}, 股票代码: {}, 当前价: {}",
                            userId, stockCode, analysisResult.getCurrentPrice());
                }
            } else {
                log.warn("股票数据分析失败 - 用户ID: {}, 股票代码: {}", userId, stockCode);
            }

        } catch (Exception e) {
            log.error("执行异动预警检查任务失败 - 用户ID: {}, 股票代码: {}", userId, stockCode, e);
        }
    }

    /**
     * 获取用户股票关联关系
     */
    private ScorpionUserStockRelationDO getUserStockRelation(Long userId, String stockCode) {
        LambdaQueryWrapper<ScorpionUserStockRelationDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ScorpionUserStockRelationDO::getUserId, userId)
                .eq(ScorpionUserStockRelationDO::getStockCode, stockCode)
                .eq(ScorpionUserStockRelationDO::getIsDeleted, (byte) 0);
        return stockRelationMapper.selectOne(queryWrapper);
    }

    /**
     * 获取股票实时数据
     */
    private StockRealTimeInfoSingleResponse getStockRealTimeData(String stockCode) {
        try {
            return akShareMcpService.stockIndividualInfoEm(stockCode);
        } catch (Exception e) {
            log.error("调用AkShare接口获取股票数据失败 - 股票代码: {}", stockCode, e);
            return null;
        }
    }

    /**
     * 获取库内上一条记录的价格
     */
    private BigDecimal getLastRecordPrice(String stockCode,Long userId) {
        try {
            // 查询该股票最新的一条异动记录
            LambdaQueryWrapper<ScorpionStockAbnormalRecordDO> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(ScorpionStockAbnormalRecordDO::getStockCode, stockCode)
                    .eq(ScorpionStockAbnormalRecordDO::getIsDeleted, (byte) 0)
                    .orderByDesc(ScorpionStockAbnormalRecordDO::getCreateTime)
                    .eq(ScorpionStockAbnormalRecordDO::getUserId, userId)
                    .last("LIMIT 1");

            ScorpionStockAbnormalRecordDO lastRecord = abnormalRecordMapper.selectOne(queryWrapper);

            if (lastRecord == null || !StringUtils.hasText(lastRecord.getAbnormalData())) {
                log.debug("股票没有历史异动记录 - 股票代码: {}", stockCode);
                return null;
            }

            // 从异动数据JSON中解析上次的价格
            try {
                JSONObject abnormalData = JSON.parseObject(lastRecord.getAbnormalData());
                BigDecimal lastPrice = abnormalData.getBigDecimal("currentPrice");
                log.debug("获取到股票上次记录价格 - 股票代码: {}, 价格: {}", stockCode, lastPrice);
                return lastPrice;
            } catch (Exception e) {
                log.warn("解析上次记录的价格数据失败 - 股票代码: {}, 异动数据: {}", stockCode, lastRecord.getAbnormalData(), e);
                return null;
            }

        } catch (Exception e) {
            log.error("查询股票历史记录失败 - 股票代码: {}", stockCode, e);
            return null;
        }
    }

    /**
     * 分析股票数据，检查是否异动
     */
    private StockAnalysisResult analyzeStockData(List<StockRealTimeInfo> stockDataList, AlertConfig alertConfig, String stockCode,Long userId) {
        try {
            if (stockDataList == null || stockDataList.isEmpty()) {
                log.warn("股票数据列表为空 - 股票代码: {}, 用户ID: {}", stockCode, userId);
                return null;
            }

            if (alertConfig == null) {
                log.warn("预警配置为空 - 股票代码: {}, 用户ID: {}", stockCode, userId);
                return null;
            }

            if (!StringUtils.hasText(stockCode)) {
                log.warn("股票代码为空 - 用户ID: {}", userId);
                return null;
            }

            if (userId == null) {
                log.warn("用户ID为空 - 股票代码: {}", stockCode);
                return null;
            }

        // 解析股票数据
        BigDecimal currentPrice = null;
        String stockName = null;

        for (StockRealTimeInfo info : stockDataList) {
            // 添加空值检查，防止空指针异常
            if (info == null || info.item() == null || info.value() == null) {
                log.warn("股票数据项为空，跳过处理 - 股票代码: {}, info: {}", stockCode, info);
                continue;
            }

            try {
                switch (info.item()) {
                    case "最新" -> {
                        // 检查最新价格是否为 "-"，如果是则记录日志并返回 null
                        if ("-".equals(info.value())) {
                            log.warn("股票最新价格为 \"-\"，无法获取有效价格数据 - 股票代码: {}, 用户ID: {}", stockCode, userId);
                            return null;
                        }
                        currentPrice = new BigDecimal(info.value());
                    }
                    case "股票简称" -> stockName = info.value();
                }
            } catch (NumberFormatException e) {
                log.warn("解析股票数据失败，跳过该项 - 股票代码: {}, item: {}, value: {}",
                        stockCode, info.item(), info.value(), e);
            }
        }

        if (currentPrice == null) {
            log.warn("股票数据不完整，无法获取当前价格 - 股票代码: {}", stockCode);
            return null;
        }

        // 获取库内上一条记录的价格
        BigDecimal lastRecordPrice = getLastRecordPrice(stockCode,userId);

        StockAnalysisResult result = new StockAnalysisResult();
        result.setCurrentPrice(currentPrice);
        result.setLastRecordPrice(lastRecordPrice);
        result.setStockName(stockName);

        // 如果没有上一条记录，无法计算涨跌幅，但仍然记录当前数据
        if (lastRecordPrice == null || lastRecordPrice.compareTo(BigDecimal.ZERO) == 0) {
            log.info("股票无历史记录或价格为0，无法计算涨跌幅，仅记录当前数据 - 股票代码: {}, 当前价: {}", stockCode, currentPrice);
            result.setChangeRatio(BigDecimal.ZERO);
            result.setFirstRecord(true); // 标记为首次记录
            return result;
        }

        // 计算涨跌幅 ((当前价 - 上次记录价格) / 上次记录价格) * 100
        BigDecimal changeRatio = currentPrice.subtract(lastRecordPrice).divide(lastRecordPrice, 4, RoundingMode.HALF_UP)
                .multiply(new BigDecimal("100"));

        result.setChangeRatio(changeRatio);
        result.setAbnormalType("初次正常记录");
        result.setAbnormalTypeCode(0);
        // 检查是否触发预警
        if (changeRatio.compareTo(BigDecimal.ZERO) > 0 &&
                alertConfig.getRiseRatio() != null &&
                changeRatio.compareTo(alertConfig.getRiseRatio()) >= 0) {
            // 上涨超过阈值
            result.setAbnormal(true);
            result.setAbnormalType("上涨预警");
            result.setAbnormalTypeCode(1);
            result.setTriggerThreshold(alertConfig.getRiseRatio());
        } else if (changeRatio.compareTo(BigDecimal.ZERO) < 0 &&
                alertConfig.getFallRatio() != null &&
                changeRatio.abs().compareTo(alertConfig.getFallRatio()) >= 0) {
            // 下跌超过阈值
            result.setAbnormal(true);
            result.setAbnormalType("下跌预警");
            result.setAbnormalTypeCode(2);
            result.setTriggerThreshold(alertConfig.getFallRatio());
        }

        return result;

        } catch (Exception e) {
            log.error("股票数据分析过程中发生异常 - 股票代码: {}, 用户ID: {}", stockCode, userId, e);
            return null;
        }
    }

    /**
     * 记录异动数据到数据库
     */
    private ScorpionStockAbnormalRecordDO recordAbnormalData(Long userId, String stockCode, StockRealTimeInfoSingleResponse stockData,
                                    StockAnalysisResult analysisResult, AlertConfig alertConfig) {
        try {
            ScorpionStockAbnormalRecordDO record = new ScorpionStockAbnormalRecordDO();
            record.setStockCode(stockCode);
            record.setStockName(analysisResult.getStockName());
            record.setStockBasicInfo(JSON.toJSONString(stockData.data()));

            // 设置涨跌幅
            if (analysisResult.getChangeRatio().compareTo(BigDecimal.ZERO) > 0) {
                record.setRiseRatio(analysisResult.getChangeRatio());
            } else {
                record.setFallRatio(analysisResult.getChangeRatio().abs());
            }

            // 构建异动数据JSON
            JSONObject abnormalData = new JSONObject();
            abnormalData.put("userId", userId);
            abnormalData.put("abnormalType", analysisResult.getAbnormalType());
            abnormalData.put("abnormalTypeCode", analysisResult.getAbnormalTypeCode());
            abnormalData.put("currentPrice", analysisResult.getCurrentPrice());
            abnormalData.put("lastRecordPrice", analysisResult.getLastRecordPrice());
            abnormalData.put("changeRatio", analysisResult.getChangeRatio());
            abnormalData.put("triggerThreshold", analysisResult.getTriggerThreshold());
            abnormalData.put("alertConfig", alertConfig);
            abnormalData.put("triggerTime", LocalDateUtils.dateTimeConvertString(LocalDateTime.now()));
            record.setUserId(userId);
            record.setAbnormalData(abnormalData.toJSONString());
            record.setCreateTime(LocalDateTime.now());
            record.setUpdateTime(LocalDateTime.now());
            record.setIsDeleted((byte) 0);

            abnormalRecordMapper.insert(record);
            log.info("异动记录保存成功 - 股票代码: {}, 异动类型: {}", stockCode, analysisResult.getAbnormalType());

            // 异步生成异动报告
//            if (record.getId() != null) {
//                try {
//                    abnormalReportService.generateAbnormalReportAsync(
//                            record.getId(), userId, stockCode, analysisResult.getStockName());
//                    log.info("已触发异动报告异步生成 - 记录ID: {}, 股票代码: {}", record.getId(), stockCode);
//                } catch (Exception e) {
//                    log.warn("触发异动报告生成失败，但不影响主流程 - 记录ID: {}, 股票代码: {}", record.getId(), stockCode, e);
//                }
//            }
            return record;
        } catch (Exception e) {
            log.error("保存异动记录失败 - 股票代码: {}", stockCode, e);
        }
        return null;
    }

    /**
     * 记录当前股票数据（非异动情况）
     */
    private void recordCurrentStockData(Long userId, String stockCode, StockRealTimeInfoSingleResponse stockData,
                                        StockAnalysisResult analysisResult) {
        try {
            ScorpionStockAbnormalRecordDO record = new ScorpionStockAbnormalRecordDO();
            record.setStockCode(stockCode);
            record.setStockName(analysisResult.getStockName());
            record.setStockBasicInfo(JSON.toJSONString(stockData.data()));

            // 正常记录，没有涨跌幅超标
            record.setRiseRatio(null);
            record.setFallRatio(null);

            // 构建当前数据JSON
            JSONObject currentData = new JSONObject();
            currentData.put("userId", userId);
            currentData.put("recordType", "初次正常记录");
            currentData.put("currentPrice", analysisResult.getCurrentPrice());
            currentData.put("lastRecordPrice", analysisResult.getLastRecordPrice());
            currentData.put("changeRatio", analysisResult.getChangeRatio());
            currentData.put("recordTime", LocalDateTime.now());

            record.setUserId(userId);
            record.setAbnormalData(currentData.toJSONString());
            record.setCreateTime(LocalDateTime.now());
            record.setUpdateTime(LocalDateTime.now());
            record.setIsDeleted((byte) 0);

            abnormalRecordMapper.insert(record);
            log.debug("正常股票数据记录成功 - 股票代码: {}, 当前价: {}", stockCode, analysisResult.getCurrentPrice());

        } catch (Exception e) {
            log.error("保存正常股票数据失败 - 股票代码: {}", stockCode, e);
        }
    }

    /**
     * 发送预警推送通知（使用模板消息）
     */
    private void sendAlertNotification(Long userId, String stockCode, StockAnalysisResult analysisResult) {
        try {
            // 构建通知DTO
            StockAlertNotificationDTO notification = new StockAlertNotificationDTO();
            notification.setStockCode(stockCode);
            notification.setStockName(analysisResult.getStockName());
            notification.setCurrentPrice(analysisResult.getCurrentPrice());
            notification.setChangeRatio(analysisResult.getChangeRatio());
            notification.setAbnormalType(analysisResult.getAbnormalType());
            notification.setTriggerThreshold(analysisResult.getTriggerThreshold());
            notification.setAlertTime(LocalDateTime.now());
            notification.setAbnormalRecordId(analysisResult.getAbnormalRecordId());

            // 发送微信模板消息
            boolean success = wechatNotificationService.sendStockAlertTemplateMessage(userId, notification);

            if (success) {
                log.info("股票异动预警模板消息发送成功 - 用户ID: {}, 股票代码: {}, 异动类型: {}, 涨跌幅: {}%",
                        userId, stockCode, analysisResult.getAbnormalType(), analysisResult.getChangeRatio());
            } else {
                log.warn("股票异动预警模板消息发送失败 - 用户ID: {}, 股票代码: {}, 异动类型: {}, 涨跌幅: {}%",
                        userId, stockCode, analysisResult.getAbnormalType(), analysisResult.getChangeRatio());
            }

        } catch (Exception e) {
            log.error("发送预警推送通知异常 - 用户ID: {}, 股票代码: {}", userId, stockCode, e);
        }
    }

    /**
     * 生成异动HTML报告
     * 包含异动分析和完整的财务分析内容（参照analyzeStockAbnormal方法的分析维度）
     */
    private void generateAbnormalHtmlReport(Long userId, String stockCode, StockRealTimeInfoSingleResponse stockData,
                                           StockAnalysisResult analysisResult, AlertConfig alertConfig) {
        try {
            log.info("开始生成异动HTML报告（包含财务分析） - 用户ID: {}, 股票代码: {}, 异动类型: {}",
                    userId, stockCode, analysisResult.getAbnormalType());

            // 第一步：收集股票财务数据进行完整分析
            StockAnalysisReportDTO financialReport = null;
            try {
                log.info("收集股票财务数据用于异动报告 - 股票代码: {}", stockCode);
                financialReport = stockAnalysisService.collectStockFinancialDataForAnalysis(stockCode);

                if (financialReport != null) {
                    // 第二步：进行AI财务分析，生成多维度分析内容
                    log.info("执行AI财务分析 - 股票代码: {}", stockCode);
                    financialReport = stockAIAnalysisService.generateFinancialAnalysisReport(financialReport);
                    log.info("AI财务分析完成 - 股票代码: {}, 综合评分: {}, 投资建议: {}",
                            stockCode, financialReport.getOverallScore(), financialReport.getInvestmentRecommendation());
                } else {
                    log.warn("无法获取财务数据，将生成简化版异动报告 - 股票代码: {}", stockCode);
                }
            } catch (Exception e) {
                log.error("财务数据收集或分析失败，继续生成基础异动报告 - 股票代码: {}, 错误: {}", stockCode, e.getMessage(), e);
            }

            // 第二步：生成包含财务分析的综合异动HTML报告
            String htmlContent;
            if (financialReport != null) {
                // 生成包含财务分析的综合报告
                log.info("生成包含财务分析的综合异动HTML报告 - 股票代码: {}", stockCode);
                htmlContent = abnormalPdfReportService.generateComprehensiveAbnormalReportHtml(
                        userId, stockCode, stockData, analysisResult, alertConfig, financialReport);
            } else {
                // 回退到基础异动报告
                log.info("生成基础异动HTML报告 - 股票代码: {}", stockCode);
                htmlContent = abnormalPdfReportService.generateAbnormalReportHtml(
                        userId, stockCode, stockData, analysisResult, alertConfig);
            }

            if (StringUtils.hasText(htmlContent)) {
                // 上传HTML到OSS并获取完整URL
                String htmlUrl = ossUploadService.uploadHtmlReport(htmlContent, stockCode, userId);

                if (StringUtils.hasText(htmlUrl)) {
                    // 更新数据库记录，保存HTML URL
                    updateAbnormalRecordWithReportUrl(userId, stockCode, htmlUrl, "HTML");
                    log.info("异动HTML报告生成并上传成功 - 用户ID: {}, 股票代码: {}, HTML URL: {}, 包含财务分析: {}",
                            userId, stockCode, htmlUrl, financialReport != null);
                } else {
                    log.warn("HTML报告上传失败 - 用户ID: {}, 股票代码: {}", userId, stockCode);
                }
            } else {
                log.warn("HTML报告生成失败 - 用户ID: {}, 股票代码: {}", userId, stockCode);
            }

        } catch (Exception e) {
            log.error("生成异动HTML报告异常 - 用户ID: {}, 股票代码: {}", userId, stockCode, e);
        }
    }

    /**
     * 保留原有的PDF生成方法供将来使用
     * 生成异动PDF报告（备用方法，字体问题解决后可使用）
     */
    private void generateAbnormalPdfReportBackup(Long userId, String stockCode, StockRealTimeInfoSingleResponse stockData,
                                                StockAnalysisResult analysisResult, AlertConfig alertConfig) {
        try {
            log.info("开始生成异动PDF报告（备用方法） - 用户ID: {}, 股票代码: {}, 异动类型: {}",
                    userId, stockCode, analysisResult.getAbnormalType());

            // 收集股票财务数据进行完整分析
            StockAnalysisReportDTO financialReport = null;
            try {
                financialReport = stockAnalysisService.collectStockFinancialDataForAnalysis(stockCode);
                if (financialReport != null) {
                    financialReport = stockAIAnalysisService.generateFinancialAnalysisReport(financialReport);
                }
            } catch (Exception e) {
                log.error("财务数据收集失败，使用基础PDF报告 - 股票代码: {}, 错误: {}", stockCode, e.getMessage(), e);
            }

            // 生成PDF报告
            byte[] pdfBytes;
            if (financialReport != null) {
                pdfBytes = abnormalPdfReportService.generateComprehensiveAbnormalReportPdf(
                        userId, stockCode, stockData, analysisResult, alertConfig, financialReport);
            } else {
                pdfBytes = abnormalPdfReportService.generateAbnormalReportPdf(
                        userId, stockCode, stockData, analysisResult, alertConfig);
            }

            if (pdfBytes != null && pdfBytes.length > 0) {
                String pdfUrl = ossUploadService.uploadStockAnalysisReport(pdfBytes, stockCode, userId);
                if (StringUtils.hasText(pdfUrl)) {
                    updateAbnormalRecordWithReportUrl(userId, stockCode, pdfUrl, "PDF");
                    log.info("异动PDF报告生成并上传成功（备用方法） - 用户ID: {}, 股票代码: {}, PDF URL: {}",
                            userId, stockCode, pdfUrl);
                }
            }

        } catch (Exception e) {
            log.error("生成异动PDF报告异常（备用方法） - 用户ID: {}, 股票代码: {}", userId, stockCode, e);
        }
    }

    /**
     * 更新异动记录的报告URL（支持HTML和PDF）
     */
    private void updateAbnormalRecordWithReportUrl(Long userId, String stockCode, String reportUrl, String reportType) {
        try {
            // 查询该用户该股票最新的异动记录
            LambdaQueryWrapper<ScorpionStockAbnormalRecordDO> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(ScorpionStockAbnormalRecordDO::getUserId, userId)
                    .eq(ScorpionStockAbnormalRecordDO::getStockCode, stockCode)
                    .eq(ScorpionStockAbnormalRecordDO::getIsDeleted, (byte) 0)
                    .orderByDesc(ScorpionStockAbnormalRecordDO::getCreateTime)
                    .last("LIMIT 1");

            ScorpionStockAbnormalRecordDO record = abnormalRecordMapper.selectOne(queryWrapper);

            if (record != null) {
                record.setAbnormalReportType(reportType.toLowerCase());
                record.setAbnormalReportAttachmentUrl(reportUrl);
                record.setUpdateTime(LocalDateTime.now());

                int updateCount = abnormalRecordMapper.updateById(record);
                if (updateCount > 0) {
                    log.info("更新异动记录{}报告URL成功 - 记录ID: {}, URL: {}", reportType, record.getId(), reportUrl);
                } else {
                    log.warn("更新异动记录{}报告URL失败 - 记录ID: {}", reportType, record.getId());
                }
            } else {
                log.warn("未找到对应的异动记录 - 用户ID: {}, 股票代码: {}", userId, stockCode);
            }

        } catch (Exception e) {
            log.error("更新异动记录{}报告URL异常 - 用户ID: {}, 股票代码: {}", reportType, userId, stockCode, e);
        }
    }

    /**
     * 更新异动记录的PDF URL（保留原方法供向后兼容）
     */
    private void updateAbnormalRecordWithPdfUrl(Long userId, String stockCode, String pdfUrl) {
        updateAbnormalRecordWithReportUrl(userId, stockCode, pdfUrl, "PDF");
    }

}
